package org.pada.domain.event;

import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @author pengshen
 * @date 2022.05.21 09:29
 */
public class EventBus {

    private static ExecutorService defaultExecutor = new ThreadPoolExecutor(Runtime.getRuntime().availableProcessors() + 1,
            Runtime.getRuntime().availableProcessors() + 1,
            0L, TimeUnit.MILLISECONDS,
            new LinkedBlockingQueue<Runnable>(1000));

    public static void dispatchDomainEvent(List<AbstractDomainEvent> domainEventList) {
        dispatchDomainEvent(domainEventList, false);
    }

    public static void dispatchDomainEvent(List<AbstractDomainEvent> domainEventList, boolean async) {
        domainEventList.forEach(x -> dispatch(x, async));
    }

    public static void dispatch(AbstractDomainEvent event) {
        dispatch(event, false);
    }

    public static void dispatch(AbstractDomainEvent event, boolean async) {
        final List<IEventHandler> handlerList = EventHub.getEventHandler(event.getClass());
        if (async) {
            handlerList.forEach(x -> {
                defaultExecutor.submit(() -> {
                    x.handle(event);
                });
            });
        } else {
            handlerList.forEach(x -> x.handle(event));
        }
    }
}
